import IpcParams from "../IpcParams";
import { createAgent } from './utils';
import Axios from 'axios';
import axiosRetry from 'axios-retry';

export default class TimefarmGame {
  constructor(tokenInfo) {
    this.tokenInfo = tokenInfo
    const agent = createAgent(this.tokenInfo.proxy)
    const headers = {
      // "Referer": "https://hamsterkombatgame.io/",
      "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_7_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",
    }
    this.axios = Axios.create({
      headers: headers,
      httpAgent: agent,
      httpsAgent: agent,
    })
    axiosRetry(this.axios, {
      retries: 3, retryDelay: (retryCount) => {
        return 2000
      }
    });
  }

  random_str(length) {
    var str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var result = '';
    for (var i = length; i > 0; --i)
      result += str[Math.floor(Math.random() * str.length)];
    return result;
  }

  getRandomIntInclusive(min, max) {
    const minCeiled = Math.ceil(min);
    const maxFloored = Math.floor(max);
    return Math.floor(Math.random() * (maxFloored - minCeiled + 1) + minCeiled); // 包含最小值和最大值
  }

  async run() {
    try {
      const axios = this.axios
      let webSessionUrl = this.tokenInfo.tgweb
      if (webSessionUrl.startsWith("https://") == false) {
        console.error(`${this.tokenInfo.phone}  error session url ${webSessionUrl}`);
        return
      }
      webSessionUrl = decodeURIComponent(webSessionUrl)
      let session = webSessionUrl.split("#tgWebAppData=")[1]
      session = session.split("&tgWebAppVersion")[0]

      // if ( session.indexOf('username') <= 0) { // At the first time, we need check if the user registed. If the URL value has not inclulded username value, it means the current account has not registed. Need register first. 
      let user_name = session.slice(session.indexOf('first_name') + 19, session.indexOf('last_name') - 9)
      user_name = user_name.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g,'');
      user_name = user_name + this.random_str(8)

      // parse user_id
      const user_id = session.slice(session.indexOf('user=%7B%22id%22%3A') + 19, session.indexOf('%2C%22first_name'))

      // console.log("session   : ", session)
      // console.log("user_name : ", user_name)
      // console.log("user_id   : ", user_id)

      const auth_token_payload = {
        'initData': session,
        'platform': 'android'
      }

      const req_header = {
        'content-type': 'application/json',
      }

      // console.log(auth_token_payload)

      let access_token = ''

      /* 1. register or get the access token */
      await axios.post('https://tg-bot-tap.laborx.io/api/v1/auth/validate-init/v2', auth_token_payload, {
        headers: req_header,
      }).then(response => {
        access_token = response.data.token
      }).catch(function (error) {
        // console.log(error)
        // Try to register user firstly
      })

      const authed_token = {
        'authorization': 'Bearer ' + access_token,
        'content-type': 'application/json',
      }

      // https://tg-bot-tap.laborx.io/api/v1/farming/finish

      /* 1. claim farming */
      await axios.post('https://tg-bot-tap.laborx.io/api/v1/farming/finish', {}, {
        headers: authed_token,
      }).then(response => {
        // console.log(response)
      }).catch(function (error) {
        // console.log(error)
        // Try to register user firstly
      })

      /* 2. strat farming */
      await axios.post('https://tg-bot-tap.laborx.io/api/v1/farming/start', {}, {
        headers: authed_token,
      }).then(response => {
        // console.log(response)
      }).catch(function (error) {
        // console.log(error)
        // Try to register user firstly
      })

      const sleepNow = (delay) => new Promise((resolve) => setTimeout(resolve, delay))

      /* 3. gether all task informations */
      let tasks = []

      await axios.get('https://tg-bot-tap.laborx.io/api/v1/tasks', {
        headers: authed_token,
      }).then(response => {
        response.data.forEach(function (taskKey, taskValue) {
          tasks.push(taskKey)
        })

      }).catch(function (error) {
        // console.log(error)
        // Try to register user firstly
      })

      /* 4. loop work on all task, sleep while one after one */
      for (let i = 0; i < tasks.length; i++) {
        const task_key = tasks[i]
        // console.log(task_key.id)
        // https://earn-domain.blum.codes/api/v1/tasks/f83c525c-9844-469b-a104-817814f337e7/start
        axios.post('https://tg-bot-tap.laborx.io/api/v1/tasks/' + task_key.id + '/submissions', {}, {
          headers: authed_token
        }).then(response1 => {
          // console.log(response1)
        }).catch(function (error1) {
          // console.log(error1)
        })

        await sleepNow(3340)
      }

      /* 5. loop claim all task, sleep while one after one */
      for (let i = 0; i < tasks.length; i++) {
        const task_key = tasks[i]
        // console.log(task_key.id)
        //https://tg-bot-tap.laborx.io/api/v1/tasks/666414ff5e7893dd79f8b97a/claims
        axios.post('https://tg-bot-tap.laborx.io/api/v1/tasks/' + task_key.id + '/claims', {}, {
          headers: authed_token
        }).then(response1 => {
          // console.log(response1)
        }).catch(function (error1) {
          // console.log(error1)
        })

        await sleepNow(3340)
      }
      
      /* 6. Get user balance again, and update to database */
      const self = this
      await axios.get('https://tg-bot-tap.laborx.io/api/v1/farming/info', {
        headers: authed_token
      }).then(response => {
        self.tokenInfo.score = response.data.balance
        // userBalance = response.data.balance
      }).catch(function (error) {
        // console.log(error)
      })
      const date = (new Date()).toLocaleString()
      this.tokenInfo.gameupdate = date
      this.tokenInfo.count = (this.tokenInfo.count || 0) + 1
      console.log(date, "timefarm end", this.tokenInfo.phone, "score: ", this.tokenInfo.score)
      return new IpcParams("runTimefarm", this.tokenInfo)
    } catch (error) {
      const date = (new Date()).toLocaleString()
      console.log(date, "timefarm error", this.tokenInfo.phone)
      // console.error(error)
      return new IpcParams("runTimefarm", this.tokenInfo, error)
    }
  }
}